﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using TestApp.Flowchart.Model;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Data;
using Newtonsoft.Json;
using System.Windows.Media;
using System.Windows.Shapes;

namespace TestApp.Flowchart.Model
{
    [JsonObject(MemberSerialization.OptIn)]
    class Arrow : FlowNode
    {
        private string _p1 = "90, 90";
        [JsonProperty]
        public string P1
        {
            get { return _p1; }
            set
            {
                _p1 = value;
                OnPropertyChanged("P1");
            }
        }

        private string _p2 = "10, 10";
        [JsonProperty]
        public string P2
        {
            get { return _p2; }
            set
            {
                _p2 = value;
                OnPropertyChanged("P2");
            }
        }

        private bool _show_arrow_in_p1 = true;
        [JsonProperty]
        public bool ShowArrowInP1
        {
            get { return _show_arrow_in_p1; }
            set
            {
                _show_arrow_in_p1 = value;
                OnPropertyChanged("ShowArrowInP1");
            }
        }

        private bool _show_arrow_in_p2 = true;
        [JsonProperty]
        public bool ShowArrowInP2
        {
            get { return _show_arrow_in_p2; }
            set
            {
                _show_arrow_in_p2 = value;
                OnPropertyChanged("ShowArrowInP2");
            }
        }
        private int _thickness = 1;
        [JsonProperty]
        public int Thickness
        {
            get { return _thickness; }
            set
            {
                _thickness = value;
                OnPropertyChanged("Thickness");
            }
        }

        private string _color = "255, 157, 157, 157";
        [JsonProperty]
        public string Color
        {
            get { return _color; }
            set
            {
                _color = value;
                OnPropertyChanged("Color");
            }
        }

        public Arrow() { }

        public override FrameworkElement CreateContent()
        {
            var textBlock = base.CreateContent() as TextBlock;
                       
            var canvas = new Canvas();

            List<int> list1 = UIUtils.convertString(_p1);
            List<int> list2 = UIUtils.convertString(_p2);

            Line myLine = new Line();
            myLine.X1 = list1[0];
            myLine.Y1 = list1[1];
            myLine.X2 = list2[0];
            myLine.Y2 = list2[1];

            myLine.StrokeThickness = _thickness;

            var mySolidColorBrush = new SolidColorBrush();
            mySolidColorBrush.Color = UIUtils.convertRGB(_color);
            myLine.Stroke = mySolidColorBrush;

            canvas.Children.Add(myLine);

            double original_x = myLine.X1;
            double original_y = myLine.Y1;
            double another_x = myLine.X2;
            double another_y = myLine.Y2;
            if (myLine.X2 < myLine.X1)
            {
                original_x = myLine.X2;
                original_y = myLine.Y2;
                another_x = myLine.X1;
                another_y = myLine.Y1;
            }
            else if (myLine.X2 == myLine.X1 && myLine.Y2 < myLine.Y1)
            {
                original_x = myLine.X2;
                original_y = myLine.Y2;
                another_x = myLine.X1;
                another_y = myLine.Y1;
            }


            double distnace = UIUtils.get_distance(myLine.X1, myLine.Y1, myLine.X2, myLine.Y2);
            
            double k = UIUtils.caculate_k(myLine.X1, myLine.Y1, myLine.X2, myLine.Y2);

            double angel = Math.PI / 2;
            if (!double.IsNaN(k))
                angel = UIUtils.caculate_angle(k);
            

            if (_show_arrow_in_p1)
            {
                double x1 = 10;
                double y1 = 5;
                double x2 = 10;
                double y2 = -5;

                var points = UIUtils.getThreePoints(x1, y1, x2, y2, angel, original_x, original_y);
                points.Add(new Coor(original_x, original_y));

                for (int i = 0; i < 3; i++)
                {
                    Line myLine1 = new Line();
                    myLine1.StrokeThickness = 1;
                    myLine1.X1 = points[i].x;
                    myLine1.Y1 = points[i].y;
                    myLine1.X2 = points[(i+1)%3].x;
                    myLine1.Y2 = points[(i + 1) % 3].y;

                    var mySolidColorBrush1 = new SolidColorBrush();
                    mySolidColorBrush1.Color = UIUtils.convertRGB(_color);
                    myLine1.Stroke = mySolidColorBrush1;

                    canvas.Children.Add(myLine1);
                }
            }


            if (_show_arrow_in_p2)
            {
                double x1 = distnace - 10;
                double y1 = 5;
                double x2 = distnace - 10;
                double y2 = -5;

                var points = UIUtils.getThreePoints(x1, y1, x2, y2, angel, original_x, original_y);
                points.Add(new Coor(another_x, another_y));

                for (int i = 0; i < 3; i++)
                {
                    Line myLine1 = new Line();
                    myLine1.StrokeThickness = 1;
                    myLine1.X1 = points[i].x;
                    myLine1.Y1 = points[i].y;
                    myLine1.X2 = points[(i + 1) % 3].x;
                    myLine1.Y2 = points[(i + 1) % 3].y;

                    var mySolidColorBrush1 = new SolidColorBrush();
                    mySolidColorBrush1.Color = UIUtils.convertRGB(_color);
                    myLine1.Stroke = mySolidColorBrush1;

                    canvas.Children.Add(myLine1);
                }
            }


            Canvas.SetLeft(textBlock, (myLine.X2 + myLine.X1) / 2);
            Canvas.SetTop(textBlock, (myLine.Y2 + myLine.Y1) / 2 - textBlock.Height/2);
            
            canvas.Children.Add(textBlock);

            return canvas;
        }

        public FlowNode Json2Obj(string value)
        {
            return JSONUtils.Json2Obj<Arrow>(value);
        }

    }
}
